package cn.roadtrip.musermodule.spi.login;

import cn.roadtrip.musermodule.dao.userlayout.UserBindRoleMapper;
import cn.roadtrip.musermodule.dao.userlayout.UserInforMapper;
import cn.roadtrip.musermodule.dao.userlayout.UserLoginBindMapper;
import cn.roadtrip.musermodule.dao.userlayout.po.UserBindRole;
import cn.roadtrip.musermodule.dao.userlayout.po.UserInforWithBLOBs;
import cn.roadtrip.musermodule.dao.userlayout.po.UserLoginBind;
import cn.roadtrip.umysqlmodule.transaction.TransactionRollback;
import cn.roadtrip.uredismodule.util.RedisUtil;
import cn.roadtrip.utilmodule.util.*;
import cn.roadtrip.utilmodule.util.enumpck.*;
import cn.roadtrip.utilmodule.wechat.MiniPromUtil;
import com.github.yitter.idgen.YitIdHelper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信小程序登录
 */
@Component
public class WeChatMinLoginImpl implements UserLogin {
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private TransactionRollback transactionRollback;
    @Autowired
    private RedisUtil redisUtil;
    private static String spkey = Enum_LoginPlat.WeiChatMiniProm.getCode();
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    private MiniPromUtil miniPromUtil;

    @Override
    public DataBean loginAndRegistry(Map<String, String> properties) {
        String code = properties.get("code");//登录凭证
        String tel = properties.get("tel");//电话
        String nickName = properties.get("nickName");//昵称
        String avatarUrl = properties.get("avatarUrl");//头像

        //微信小程序登录回调，获取openid
        Map<String, String> rsmap = miniPromUtil.getLoginSessionByCode(code);
        String openId = rsmap.get("openid");
        if (openId == null || openId.equals("")) {
            return DataBean.err("code-err", rsmap.get("errmsg"));
        }
        //验证数据库是否存在用户

        try (SqlSession sql = sqlSessionFactory.openSession(true)) {
            UserLoginBindMapper mapper = sql.getMapper(UserLoginBindMapper.class);
            UserLoginBind loginMethod = mapper.getUser(Enum_LoginPlat.WeiChatMiniProm.getCode(), openId);
            if (loginMethod != null) {
                UserInforMapper userMapper = sql.getMapper(UserInforMapper.class);
                UserInforWithBLOBs user = userMapper.selectByPrimaryKey(loginMethod.getOpenid());
                user.setLastlogintime(System.currentTimeMillis());
//                mapper.updateByPrimaryKeySelective(loginMethod);
                userMapper.updateByPrimaryKeySelective(user);
                return DataBean.suc(user, 1, "exist-user", "用户已注册");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("err", e.getMessage());
        }
        //保存用户数据
        {
            return transactionRollback.transaction(
                    () -> {
                        try (SqlSession sql = sqlSessionFactory.openSession(true)) {
                            UserLoginBindMapper loginmapper = sql.getMapper(UserLoginBindMapper.class);
                            UserInforMapper userMapper = sql.getMapper(UserInforMapper.class);
                            RLock lock = redissonClient.getLock(this.getClass().getName());
                            lock.tryLock(3, TimeUnit.SECONDS);

                            //保存用户信息
                            UserInforWithBLOBs user = new UserInforWithBLOBs(
                                    YitIdHelper.nextId() + "",
                                    Enum_UserInforStats.Open.getCode(),
                                    tel,
                                    nickName,
                                    Enum_UserSex.Secret.getCode(),
                                    System.currentTimeMillis(),
                                    System.currentTimeMillis(),
                                    avatarUrl,
                                    "{}",
                                    "#"
                            );
                            userMapper.insert(user);

                            //保存登录方式
                            UserLoginBind loginMethod = new UserLoginBind(
                                    YitIdHelper.nextId() + "",
                                    user.getId(),
                                    Enum_LoginPlat.WeiChatMiniProm.getCode(),
                                    openId,
                                    "",
                                    "{}"
                            );
                            loginmapper.insert(loginMethod);

                            //保存角色
                            UserBindRoleMapper roleMapper = sql.getMapper(UserBindRoleMapper.class);
                            java.util.List<UserBindRole> roles = roleMapper.getUserRoles(user.getId());
                            if (roles == null || roles.isEmpty()) {
                                //新增普通角色
                                UserBindRole r = new UserBindRole(
                                        YitIdHelper.nextId() + "",
                                        false,
                                        Enum_UserBindRoleStats.Active.getCode(),
                                        user.getId(),
                                        Enum_UserRoleType.Normal.getCode(),
                                        System.currentTimeMillis(),
                                        System.currentTimeMillis(),
                                        "{}"
                                );
                                roleMapper.insert(r);
                            }
                            sql.commit();
                            lock.unlock();
                            return DataBean.suc(user, 1, "suc", "操作完成");
                        }
                    },
                    (ex) -> {
                        return DataBean.err("trans-err", "执行事务错误", ex.getMessage());
                    }
            );
        }


    }

    @Override
    public boolean supports(String key) {
        return key.equals(spkey);
    }
}
